﻿using AutoMapper;
using SqlSugar;
using System.Linq;
using System.Linq.Expressions;
using XieCan.Core.DTO;
using XieCan.Core.Entity;
using XieCan.Core.IReposity;

namespace XieCan.Core.Repository
{
  public abstract class BaseRepository<TEntity, TCreateModel, TUpdateModel, TListModel, TSingleModel>
    : SimpleClient<TEntity>, IBaseRepository<TEntity, TCreateModel, TUpdateModel, TListModel, TSingleModel>
    where TEntity : BaseEntity, new()
    where TCreateModel : BaseCreateModel, new()
    where TUpdateModel : BaseUpdateModel, new()
    where TListModel : BaseListModel, new()
    where TSingleModel : BaseSingleModel, new()
  {
    /// <summary>
    /// 多租户
    /// </summary>
    public ITenant Tenant => Context.AsTenant();
    /// <summary>
    /// 映射
    /// </summary>
    protected readonly IMapper mapper;

    public BaseRepository(ISqlSugarClient db, IMapper mapper)
    {
      Context = db.AsTenant().GetConnectionScopeWithAttr<TEntity>();
      this.mapper = mapper;
    }

    public void BeginTran()
    {
      Tenant.BeginTran();
    }

    public void CommitTran()
    {
      Tenant.CommitTran();
    }

    public async Task<OperateResult<bool>> DeleteAsync(Guid id, string? deletor, CancellationToken cancel = default)
    {
      try
      {
        var entity = await GetFirstAsync(p => p.Id == id, cancel);
        if (entity == null)
          return OperateResult<bool>.Succeeded(true, "未找到要删除的数据！");
        entity.DeleteTime = DateTime.Now;
        entity.IsDeleted = true;
        entity.DeletorId = deletor;
        var result = await base.UpdateAsync(entity, cancel);
        return result ? OperateResult<bool>.Succeeded(true, "删除成功！") : OperateResult<bool>.Failed("删除失败！");
      }
      catch (Exception ex)
      {
        return OperateResult<bool>.Failed(ex);
      }
    }

    public async Task<OperateResult<bool>> DeleteAsync(Expression<Func<TEntity, bool>> where, string? deletor, CancellationToken cancel = default)
    {
      try
      {
        var entities = await base.GetListAsync(where, cancel);
        entities.ForEach(entity =>
        {
          entity.DeleteTime = DateTime.Now;
          entity.IsDeleted = true;
          entity.DeletorId = deletor;
        });
        var result = await base.UpdateRangeAsync(entities, cancel);
        return result ? OperateResult<bool>.Succeeded(true, "删除成功！") : OperateResult<bool>.Failed("删除失败！");
      }
      catch (Exception ex)
      {
        return OperateResult<bool>.Failed(ex);
      }
    }

    public async Task<OperateResult<TSingleModel?>> GetAsync(Guid id, CancellationToken cancel = default)
    {
      try
      {
        var entity = await base.GetFirstAsync(p => p.Id == id && !p.IsDeleted, cancel);
        if (entity == null)
          return OperateResult<TSingleModel?>.Failed("未找到相关数据！");
        return OperateResult<TSingleModel?>.Succeeded(mapper.Map<TSingleModel>(entity), "查询成功！");
      }
      catch (Exception ex)
      {
        return OperateResult<TSingleModel?>.Failed(ex);
      }
    }

    public async Task<OperateResult<TSingleModel?>> GetAsync(Expression<Func<TEntity, bool>> where, CancellationToken cancel = default)
    {
      try
      {
        var entity = await GetFirstAsync(where, cancel);
        if (entity == null || entity.IsDeleted)
          return OperateResult<TSingleModel?>.Failed("未找到相关数据！");
        return OperateResult<TSingleModel?>.Succeeded(mapper.Map<TSingleModel>(entity), "查询成功！");
      }
      catch (Exception ex)
      {
        return OperateResult<TSingleModel?>.Failed(ex);
      }
    }
    public async Task<OperateResult<bool>> InsertAsync(TCreateModel model, CancellationToken cancel = default)
    {
      try
      {
        var entity = mapper.Map<TEntity>(model);
        var result = await base.InsertAsync(entity, cancel);
        return result ? OperateResult<bool>.Succeeded(true, "添加成功！") : OperateResult<bool>.Failed("添加失败！");
      }
      catch (Exception ex)
      {
        return OperateResult<bool>.Failed(ex);
      }
    }

    public void RollbackTran()
    {
      Tenant.RollbackTran();
    }

    public async Task<OperateResult<bool>> UpdateAsync(Guid id, TUpdateModel model, CancellationToken cancel = default)
    {
      try
      {
        var entity = mapper.Map<TEntity>(model);
        entity.Id = id;
        var result = await base.UpdateAsync(entity, cancel);
        return result ? OperateResult<bool>.Succeeded(true, "修改成功！") : OperateResult<bool>.Failed("修改失败！");
      }
      catch (Exception ex)
      {
        return OperateResult<bool>.Failed(ex);
      }
    }

    public new async Task<OperateResult<List<TListModel>>> GetListAsync(Expression<Func<TEntity, bool>> where, CancellationToken cancel)
    {
      try
      {
        var list = await base.GetListAsync(where, cancel);
        return OperateResult<List<TListModel>>.Succeeded(mapper.Map<List<TListModel>>(list.Where(p => !p.IsDeleted)), "查询成功！");
      }
      catch (Exception ex)
      {
        return OperateResult<List<TListModel>>.Failed(ex);
      }
    }

    public new async Task<OperateResult<bool>> UpdateAsync(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> where, CancellationToken cancel)
    {
      try
      {
        var result = await base.UpdateAsync(columns, where, cancel);
        return result ? OperateResult<bool>.Succeeded(true, "修改成功！") : OperateResult<bool>.Failed("修改失败！");
      }
      catch (Exception ex)
      {
        return OperateResult<bool>.Failed(ex);
      }
    }
  }
}
